// File: jmcomic-core/src/main/java/dev/jukomu/common/util/system/SystemUtils.java
package dev.jukomu.common.util.system;

import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * 对应Python的sys_util.py中的通用系统工具方法。
 * 包含工作区管理、控制台输出、字符串处理等。
 */
public class SystemUtils {

    // 对应Python的_workspace，全局工作区路径
    private static String applicationWorkspace = "";

    /**
     * 获取或设置应用程序的工作区路径。
     * 如果子文件路径不为null，则返回子文件的完整路径。
     * 在Java中，由于文件操作的API不同，这里只处理路径拼接，不直接返回IO流。
     *
     * @param subFile 子文件或子目录相对路径 (可选)
     * @param isDir   如果subFile表示一个目录，则为true (可选)
     * @return 完整路径字符串
     */
    public static String getWorkspace(String subFile, boolean isDir) {
        String baseWorkspace;
        if (applicationWorkspace != null && !applicationWorkspace.isEmpty()) {
            baseWorkspace = applicationWorkspace;
        } else {
            // 获取当前工作目录
            baseWorkspace = System.getProperty("user.dir");
        }

        if (subFile == null || subFile.isEmpty()) {
            return baseWorkspace;
        }

        // 统一路径分隔符为Unix风格
        String fixedSubFile = subFile.replace("\\", "/").replaceAll("//", "/");
        String fullPath = baseWorkspace.endsWith("/") ? baseWorkspace + fixedSubFile : baseWorkspace + "/" + fixedSubFile;

        // 如果是目录，确保以斜杠结尾
        if (isDir && !fullPath.endsWith("/")) {
            fullPath += "/";
        }
        return fullPath;
    }

    /**
     * 获取或设置应用程序的工作区路径，不处理子文件。
     *
     * @return 当前工作区路径字符串
     */
    public static String getWorkspace() {
        return getWorkspace(null, false);
    }

    /**
     * 设置应用程序的工作区路径。
     *
     * @param workspacePath 新的工作区路径
     */
    public static void setApplicationWorkspace(String workspacePath) {
        applicationWorkspace = workspacePath.replace("\\", "/").replaceAll("//", "/");
    }

    /**
     * 打印分隔符。
     *
     * @param text   分隔符字符
     * @param length 长度
     */
    public static void printSep(String text, int length) {
        if (text == null || text.isEmpty()) {
            text = "-";
        }
        char sepChar = text.charAt(0); // Only use the first char
        char[] chars = new char[length];
        Arrays.fill(chars, sepChar);
        System.out.println(new String(chars));
    }

    /**
     * 打印分隔符，默认使用'-'，长度70。
     */
    public static void printSep() {
        printSep("-", 70);
    }

    /**
     * 打印醒目文本。
     *
     * @param text          文本内容
     * @param needToConfirm 是否需要确认（记录到消息中心）
     * @param surround      环绕字符（例如 "\n"）
     * @param multiple      环绕字符重复倍数
     * @param key           消息中心键（可选）
     */
    public static void printEyeCatching(String text, boolean needToConfirm, String surround, int multiple, Object key) {
        if (needToConfirm) {
            ApplicationMessageCenter.appendMsg(text, key);
        }
        String margin = new String(new char[multiple]).replace("\0", surround);
        System.out.println(margin + text + margin);
    }

    /**
     * 打印醒目文本，使用默认配置。
     *
     * @param text          文本内容
     * @param needToConfirm 是否需要确认
     */
    public static void printEyeCatching(String text, boolean needToConfirm) {
        printEyeCatching(text, needToConfirm, "\n", 1, null);
    }

    /**
     * 打印集合元素，默认以换行符分隔。
     *
     * @param data      要打印的集合
     * @param separator 分隔符
     */
    public static <T> void printList(Collection<T> data, String separator) {
        if (data == null || data.isEmpty()) {
            return;
        }
        System.out.println(data.stream().map(Object::toString).collect(Collectors.joining(separator)));
    }

    /**
     * 打印集合元素，默认以换行符分隔。
     *
     * @param data 要打印的集合
     */
    public static <T> void printList(Collection<T> data) {
        printList(data, "\n");
    }

    /**
     * 打印对象的公共字段和方法（通常是__dict__的映射）。
     *
     * @param obj       要打印的对象
     * @param separator 分隔符
     */
    public static void printObjDict(Object obj, String separator) {
        if (obj == null) {
            System.out.println("null");
            return;
        }
        if (obj instanceof Map) {
            printList(((Map<?, ?>) obj).entrySet(), separator);
        } else {
            // Java没有Python的__dict__，这里通过反射获取公共字段或使用toString()
            // 为简化，这里直接打印对象的toString()或提供一个默认行为
            // 如果需要详细的字段打印，需要迭代Class的字段并获取值
            // 为保持与Python print_obj_dict的语义一致，我们可以尝试打印所有getter方法
            List<String> properties = Arrays.stream(obj.getClass().getMethods())
                    .filter(m -> m.getName().startsWith("get") && m.getParameterCount() == 0 && m.getReturnType() != void.class)
                    .map(m -> {
                        try {
                            return m.getName().substring(3) + "=" + m.invoke(obj);
                        } catch (Exception e) {
                            return m.getName().substring(3) + "=ERROR(" + e.getMessage() + ")";
                        }
                    })
                    .collect(Collectors.toList());
            printList(properties, separator);
        }
    }

    /**
     * 打印对象的公共字段和方法，默认以换行符分隔。
     *
     * @param obj 要打印的对象
     */
    public static void printObjDict(Object obj) {
        printObjDict(obj, "\n");
    }

    // 正则表达式用于解析Unicode转义序列
    private static final Pattern UNICODE_ESCAPE_PATTERN = Pattern.compile("\\\\u([0-9a-fA-F]{4})");

    /**
     * 解析Unicode转义文本。
     * 对应Python的parse_unicode_escape_text。
     *
     * @param text 包含Unicode转义序列的文本
     * @return 解析后的文本
     */
    public static String parseUnicodeEscapeText(String text) {
        if (text == null || text.isEmpty()) {
            return text;
        }
        Matcher matcher = UNICODE_ESCAPE_PATTERN.matcher(text);
        StringBuffer sb = new StringBuffer();
        while (matcher.find()) {
            String hex = matcher.group(1);
            char ch = (char) Integer.parseInt(hex, 16);
            matcher.appendReplacement(sb, String.valueOf(ch));
        }
        matcher.appendTail(sb);
        return sb.toString().replace("\\/", "/"); // 替换Python中的 \/
    }

    /**
     * 打印当前线程的堆栈跟踪。
     * 对应Python的traceback_print_exc()。
     */
    public static void printStackTrace() {
        new Exception().printStackTrace();
    }

    /**
     * 将多行字符串转换为行迭代器（Stream）。
     *
     * @param lines 多行字符串
     * @return 每行的Stream
     */
    public static List<String> stringToLineList(String lines) {
        if (lines == null || lines.isEmpty()) {
            return Arrays.asList();
        }
        return Arrays.stream(lines.strip().split("\n"))
                .map(String::trim)
                .filter(line -> !line.isEmpty())
                .collect(Collectors.toList());
    }

    /**
     * 将多行字符串转换为Set。
     *
     * @param lines 多行字符串
     * @return 包含每行内容的Set
     */
    public static Set<String> stringToLineSet(String lines) {
        if (lines == null || lines.isEmpty()) {
            return java.util.Collections.emptySet();
        }
        return Arrays.stream(lines.strip().split("\n"))
                .map(String::trim)
                .filter(line -> !line.isEmpty())
                .collect(Collectors.toSet());
    }

    // 私有构造函数，防止实例化
    private SystemUtils() {
    }
}